package com.mew.game.core.common.handler;


import com.mew.common.dc.redis.AucRedisService;
import com.mew.common.exception.ResponseCode;
import com.mew.common.rest.bo.GameSession;
import com.mew.common.rest.bo.MewSession;
import com.zebra.common.ZebraException;
import com.zebra.remoting.config.BasisCommandCode;
import com.zebra.remoting.config.StateCode;
import com.zebra.remoting.connection.Connection;
import com.zebra.remoting.protocol.ZebraCommand;
import com.zebra.remoting.tms.AbstractServerHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Slf4j
public class ConnectionHandlerService extends AbstractServerHandler {

    @Autowired
    private EnterExitRoomHandler enterExitRoomHandler;
    @Autowired
    private AucRedisService aucRedisService;
    @Autowired
    private SessionManager slotsSessionManager;


    @Override
    public void doHandler(ZebraCommand command) throws Exception {
        MewSession session = aucRedisService.getSession(command.getUserId());
        GameSession slotsSession = slotsSessionManager.get(command.getUserId());

        if (BasisCommandCode.OFFLINE.cmd() == command.getCmd()){
            log.error("Handler offline: {} {}  {}", command,
                    null == session ? "session is null" : session.toString(),
                    null == slotsSession ? "gameSession is null" : slotsSession.toString());
            enterExitRoomHandler.offlineByGw(command, session, slotsSession);
            return;
        }

        //初步够用
        if (BasisCommandCode.SWITCHTMS.cmd() == command.getCmd()){
            if (session == null){
                log.error("Handler SWITCHTMS MewSession is null {}", command);
                return;
            }

            if (null == slotsSession){
                log.info("Handler SWITCHTMS SlotsSession is null {}", command);
                command.setGameId(session.gid);
                enterExitRoomHandler.switchRoom(command, session);
                return;
            }

            log.info("Handler SWITCHTMS {}", command);
            slotsSession.setChannel(command.getChannel());
            return;
        }

        //-----校验-------------
        if (command.getCommandModel().isVerifyType()) {
            if (null == session || session.tk != command.getToken()){
                command.sendFailureCode(StateCode.LoginUn.code());
                log.error("Handler session failure:   {} ses:{}", command, null == session ? "" : session.toString());
                enterExitRoomHandler.offline(slotsSession);
                return;
            }
        }

        HandlerMapCmdType cmdType = HandlerMapCmdType.valueOfCode(command.getCmd());
        if (null == cmdType){
            cmdInvalid(command, slotsSession);
            return;
        }

        if (cmdType != HandlerMapCmdType.EnterRoom && cmdType != HandlerMapCmdType.ReconnectRoom){
            if (slotsSession == null){
                log.error("Handler SlotsSession is null {}", command);
                cmdInvalid(command, slotsSession);
                return;
            }
        }



        switch (cmdType){
            case Play: { doPlay(command, slotsSession); break; }

            case EnterRoom:{ enterExitRoomHandler.enterRoom(command, session, slotsSession); break;  }
            case ReconnectRoom:{ enterExitRoomHandler.reconnectRoom(command, session, slotsSession); break; }
            case ExitRoom: { enterExitRoomHandler.exitRoom(command);  break;  }

            default: {
                cmdInvalid(command, slotsSession);
            }
        }
    }

    private void doPlay(ZebraCommand command, GameSession slotsSession) throws ZebraException {
        log.info("Bet {}", command.toString());
        PlayHandler betHandler = InitializePlayHandlerMapping.getMapping(slotsSession.getVfx());
        betHandler.play(command, slotsSession);
    }


    private void  cmdInvalid(ZebraCommand command, GameSession slotsSession){
        log.error("Handler <-> CMD not mapping LoginUn {} ", command.toString());
        command.sendFailureCode(ResponseCode.LoginUn.code());
        enterExitRoomHandler.offline(slotsSession);
    }


    @Override
    public void doChannelInactive(Connection connection) throws Exception {
        List<GameSession> list = slotsSessionManager.findByChannel(connection.getChannel());
        if (null == list || list.isEmpty()){
            return;
        }
        log.error("Handler Gateway inactive: {}", connection);
        list.stream().forEach(ss -> {
            log.error("Handler Gateway inactive session: {}  ", ss.toString());
            enterExitRoomHandler.offline(ss);
        });
    }

    @Override
    public void doTmsOffline() {
        log.info("------------RA-to-TMS-Offline--1 M-exe---user-offline---------------");
    }


}



